﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Antlr.Runtime;

namespace PSLib.Parsing.Common
{
    public class ElementPosition
    {
        #region Static members

        public static ElementPosition GlobalStart = new ElementPosition(0, 0);
        public static ElementPosition GlobalEnd = new ElementPosition(int.MaxValue, int.MaxValue);

        #endregion

        #region Constructor

        public ElementPosition(int line, int posInLine)
        {
            this.Line = line;
            this.PositionInLine = posInLine;
        }

        #endregion

        #region Overrides

        public static bool operator > (ElementPosition x, ElementPosition y)
        {
            if (x == null || y == null) return false;
            return x.Line > y.Line || (x.Line == y.Line && x.PositionInLine > y.PositionInLine);
        }

        public static bool operator >= (ElementPosition x, ElementPosition y)
        {
            if (x == null || y == null) return false;
            return (x > y || x == y);
        }

        public static bool operator < (ElementPosition x, ElementPosition y)
        {
            if (x == null || y == null) return false;
            bool result = x.Line < y.Line;
            result = result || x.Line == y.Line && x.PositionInLine < y.PositionInLine;
            return  result;
        }

        public static bool operator <=(ElementPosition x, ElementPosition y)
        {
            if (x == null || y == null) return false;
            return (x < y || x == y);
        }

        public static bool operator ==(ElementPosition x, ElementPosition y)
        {
            if (Object.Equals(x, null) || Object.Equals(y, null)) return false;
            return x.Line == y.Line && x.PositionInLine == y.PositionInLine;
        }

        public static bool operator !=(ElementPosition x, ElementPosition y)
        {
            return !(x == y);
        }

        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return this.Line.GetHashCode() + this.PositionInLine.GetHashCode();
        }

        public override string ToString()
        {
            return "(" + this.Line + " -> " + this.PositionInLine + ")";
        }

        #endregion

        #region Properties

        public int Line { get; private set; }
        public int PositionInLine { get; private set; }

        #endregion
    }

    public static class ElementPositionExtension
    {
        public static ElementPosition GetPosition(this IToken token)
        {
            return new ElementPosition(token.Line, token.CharPositionInLine);
        }
    }
}
